Add EqualUnordered assertion for structs with unordered slices#1851
Add EqualUnordered assertion for structs with unordered slices#1851veeceey wants to merge 2 commits intostretchr:masterfrom
Conversation
Add deep equality comparison that treats all slices and arrays as unordered collections. Unlike ElementsMatch which only works on top-level slices, EqualUnordered handles slices nested within structs, maps, pointers, and other slices. Duplicate elements are counted correctly: [1,1,2] != [1,2,2]. Fixes stretchr#806 Signed-off-by: Varun Chawla <varun_6april@hotmail.com>
|
I don't like that unordered is applied recursively. Also, the name of the function doesn't make clear that it has this recursive behavior, so it would be easy to misuse. So 👎 |
|
Thanks for the feedback @dolmen! Those are valid concerns. You're right that the recursive unordered comparison could be surprising. A couple of thoughts:
Would either of those approaches address your concern? Happy to rework this based on what the maintainers prefer. |
|
I'm unsure about the need here. When I have to deal with something like this, which is rare, I create a normalization function I call before sending things to an asserter. It's usually a call to a slice.SortFunc with the sort I need. https://pkg.go.dev/slices#SortFunc I feel like everyone needs are different, so what you implemented in the method you created might not feed someone else need. Such as the fact it handles map, slice recursively So I would decline such feature, so more about declining the issue you are trying to solve than your implementation |
|
@ccoVeille Thanks for the honest feedback -- that's a fair perspective. You're right that everyone's comparison needs are different, and a generic recursive unordered comparison might not fit most use cases well. The If the consensus is that this doesn't belong in testify's core, I completely understand. I'll leave the PR open for a bit in case other maintainers have thoughts, but happy to close it if the general feeling is that this is better handled in userland. Thanks for taking the time to explain your reasoning. |
|
Closing this out based on the maintainer feedback. Both @dolmen and @ccoVeille raised valid concerns about the recursive behavior being too opinionated for the library's scope, and the use case being better served by userland solutions like |
Closes #806
I've been hitting this exact pain point for a while — when you have a struct with 15+ fields and one of them is a slice where order doesn't matter, you end up writing field-by-field assertions just to use
ElementsMatchon that one slice. As @lordzsolt said in the issue, "if I have to write this all out by hand, why am I even using an assertion library?"This adds
EqualUnordered(andNotEqualUnordered) which does a deep equality comparison but treats all slices/arrays as unordered collections. It recursively walks structs, maps, pointers, and nested slices — so it handles deeply nested cases too.Key details:
[1, 1, 2]!=[1, 2, 2]nilslice vs empty slice are treated as different (consistent withEqual)assertion_format.go,assertion_forward.go,require/) updated viago generateTested locally with
go test ./...— everything green.